/*   The MIT License
 *   
 *   Carina Engine
 *   Copyright (c) 2009 2010 2011 2012 Zdravko Velinov
 *   
 *   Permission is hereby granted, free of charge, to any person obtaining a copy
 *   of this software and associated documentation files (the "Software"), to deal
 *   in the Software without restriction, including without limitation the rights
 *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *   copies of the Software, and to permit persons to whom the Software is
 *   furnished to do so, subject to the following conditions:
 *
 *   The above copyright notice and this permission notice shall be included in
 *   all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *   THE SOFTWARE.
 */
#include "carina/axis.hh"

namespace Carina
{
Axis::Axis(const ResourceManagerPtr& res_mgr)
{
    m_Renderer = res_mgr->getRenderer();
    m_DepthStencilStates = m_Renderer->createDepthStencilStateObject(DepthStencilStateDescription(false, false));
    m_States = m_Renderer->createStateObject(MiscStateDescription(CE_FILL_SOLID, CE_CULL_NONE, 0, 0, false, false, false, false));

    Vector3 axis_data[] =
    {
        Vector3(0.0f, 0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f),
        Vector3(1.0f, 0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f),
        Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f),
        Vector3(0.0f, 1.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f),
        Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, 1.0f),
        Vector3(0.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f)
    };

    InputElementArray arr(2);
    arr[0].set("POSITION", VT_RGB32F, 0);
    arr[1].set("COLOR", VT_RGB32F, sizeof(Vector3));

    m_Prog = res_mgr->getShaderProgram("axis");
    m_Layout = m_Renderer->createInputLayout(m_Prog, arr);
    m_VBAxis = m_Renderer->createVideoBuffer(CE_VERTEX_BUFFER, sizeof(axis_data), axis_data, CE_STATIC_DRAW);
}

void Axis::draw(const CameraPtr& cam)
{
    assert(m_Renderer.get());
    ScopedState state(m_Renderer, m_States);
    ScopedDepthStencilState dsstate(m_Renderer, m_DepthStencilStates);
    m_Renderer->useShaderProgram(m_Prog);

    float axis_size = cam->getHeight()*0.1f;
    Matrix4 proj_mat = m_Renderer->createOrthoMatrix(0.0f, (float)cam->getWidth(), 0.0f, (float)cam->getHeight(), -axis_size, axis_size);
    Matrix4 view; view.identity();
    view.translate(Vector2(axis_size*1.1f, axis_size*1.1f));
    Matrix4 rot_mat = cam->getViewMatrix();
    rot_mat[3][0] = 0.0f;
    rot_mat[3][1] = 0.0f;
    rot_mat[3][2] = 0.0f;
    rot_mat[3][3] = 1.0f;
    view *= rot_mat;
    view.scale(axis_size);
    m_Prog->getVariable("TransformMatrix")->set(proj_mat*view);

    m_Renderer->setInputLayout(m_Layout);
    m_Renderer->setVideoBuffer(m_VBAxis, 2*sizeof(Vector3));
    m_Renderer->draw(CE_LINE_LIST, 0, 6);
}
}
